package com.bzm.common.utils;

import org.apache.commons.io.IOUtils;
import org.lionsoul.ip2region.*;
import org.springframework.core.io.ClassPathResource;

import com.alibaba.fastjson.JSON;

import lombok.Data;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author yehao
 * @version 1.0
 * @date 2020/7/21 14:40
 * @Description ip地址解析，github地址：https://github.com/lionsoul2014/ip2region
 */
public class IpParser {

    private static final String DB_FILE = "ip2region.db";

    private static DbSearcher searcher = null;
    private static Method method = null;

    static {
        DbConfig config = null;
        try {
            InputStream is = new ClassPathResource(DB_FILE).getInputStream();
            config = new DbConfig();
            searcher = new DbSearcher(config, IOUtils.toByteArray(is));
            method = searcher.getClass().getMethod("memorySearch", String.class);
        } catch (DbMakerConfigException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static IpInfo parseIp(String ip){
        if(ip == null || !Util.isIpAddress(ip)){
            return null;
        }
        try {
            double sTime = 0, cTime = 0;
            DataBlock dataBlock = null;
            sTime = System.nanoTime();
            dataBlock = (DataBlock) method.invoke(searcher, ip);
            cTime = (System.nanoTime() - sTime) / 1000000;
//            System.out.printf("%s in %.5f millseconds\n", dataBlock, cTime);
            String region = dataBlock.getRegion();
            String[] infos = region.split("\\|");
            if(infos.length > 3) {
                IpInfo ipinfo = new IpInfo(ip,infos[0],infos[2],infos[3],JSON.toJSONString(region));
                return ipinfo;
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    @Data
    public static class IpInfo {
        private String ip;
        
        private String country;
        
        private String province;
        
        private String city;
        
        private String ipJson;

        public IpInfo(String ip, String country, String province,String city,String ipJson) {
            this.ip = ip;
            this.country = country;
            this.province = province;
            this.city = city;
            this.ipJson = ipJson;
        }
    }

    public static void main(String[] args) {
        IpInfo info = IpParser.parseIp("183.14.135.170");
        System.out.println(info);
    }

}
